package mytomcat;

import mytomcat.constant.FilterConstant;
import mytomcat.core.MyRequest;
import mytomcat.core.MyResponse;
import mytomcat.dto.ServletInfo;
import mytomcat.dto.SourceInfo;
import mytomcat.dto.XmlNodeInfo;
import mytomcat.filter.base.BaseFilter;
import mytomcat.util.Dom4jParseUtil;
import mytomcat.util.FileRootUtil;
import mytomcat.util.XmlNodeUtil;
import org.dom4j.Attribute;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <ul>
 * <li>Title:  MyTomcat</li>
 * <li>Description: 初始化信息 以及 socket进行网络通信 </li>
 * <li>Copyright: Copyright (c) 2018</li>
 *
 * </ul>
 *
 * @author swc
 * @version     V1.0
 * @date 2020/4/20 0020 上午 9:54
 */
public class MyTomcat {

    private  int port;

    //servlet的映射信息
    public static Map<String,ServletInfo> urlServletMap = null;

    //过滤器接口
    private  BaseFilter baseFilter;

    //xml配置信息
    public  static XmlNodeInfo XmlNodeInfo;

    //静态资源
    public  static SourceInfo sourceInfo;


    public void start(){
        long startTime = System.currentTimeMillis();

        //初始化配置xml信息
        System.out.println(" myTomcat is start run...");
        init();

        //获取端口信息
        getXmlPort();

        System.out.println("正在读取serlvet的映射信息");
        //获取servlet信息
        initservletMapping();

        ServerSocket serverSocket =null;
        try {
            serverSocket = new ServerSocket(port);

            long endTime = System.currentTimeMillis();
            System.out.println("启动完成,耗时："+(endTime-startTime)+"ms\n\n");
            while(true){
                Socket socket = serverSocket.accept();
                InputStream inputStream =socket.getInputStream();
                OutputStream outputStream =socket.getOutputStream();

                MyRequest myRequest =new MyRequest(inputStream,this.port);
                MyResponse myResponse =new MyResponse(outputStream);

                baseFilter.filterAllowUrl(myRequest,myResponse,XmlNodeInfo);
                socket.close();
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(serverSocket!=null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //初始化xml信息
    private  void init() {
        String root = FileRootUtil.getRoot("\\src\\main\\resources\\");
        XmlNodeInfo = Dom4jParseUtil.xmlParseContext(root + "tomcat-context.xml");
    }

    //获取xml里面的port信息
    private  void getXmlPort() {
        Map<String, XmlNodeInfo> allNode = XmlNodeInfo.getAllNode();

        HashMap<String,String> keys =new HashMap<String, String>();
        XmlNodeInfo filter = XmlNodeUtil.getValue(allNode,"beans","port", 0);

        if(filter!=null){
            String portInfo = filter.getValue();
            portInfo = portInfo!=null && !"".equals(portInfo)?portInfo:"8080";
            this.port = Integer.parseInt(portInfo);
        }
    }



    //初始化映射关系==servelet
    private  void initservletMapping() {
        Map<String, XmlNodeInfo> allNode = XmlNodeInfo.getAllNode();

        //静态资源
        XmlNodeInfo sourceNode = XmlNodeUtil.getValue(allNode, "sources","source",0);
        if(sourceNode!=null){
            List attributes = sourceNode.getAttributes();
            Attribute attribute=null;
            sourceInfo = new SourceInfo();
            sourceInfo.setRealPath(Arrays.asList(sourceNode.getValue().replaceAll("\\n|\\t","").split(",")));
            for(int k=0;k<attributes.size();k++){
                attribute = (Attribute)attributes.get(k);
                if("servletClass".equals(attribute.getName())){
                    sourceInfo.setServletClass(attribute.getValue());
                }
            }
        }

        XmlNodeInfo filter = XmlNodeUtil.getValue(allNode, FilterConstant.FILTER,FilterConstant.FILTERBEAN,0);

        if(filter!=null){
            List attributes = filter.getAttributes();

            String className ="";
            Attribute attribute=null;

            for(int k=0;k<attributes.size();k++){
                attribute = (Attribute)attributes.get(k);
                if("class".equals(attribute.getName())){
                    className = attribute.getValue();
                }
            }
            try {
                Class<BaseFilter> aClass = (Class<BaseFilter>)Class.forName(className);
                baseFilter = aClass.newInstance();
                urlServletMap = baseFilter.getSerVletInfo(XmlNodeInfo);
            }  catch (Exception e) {
                e.printStackTrace();
            }

        }
    }



}
